﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Revis.VClinicNet.App.Internal;
using Revis.VClinicNet.App.Internal.Dto;
using Revis.VClinicNet.App.Internal.Dto.Validation;
using Revis.VClinicNet.UI.Internal.Mvc.Extensions;
using Revis.VClinicNet.UI.Internal.Mvc.Infrastructure;
using Revis.VClinicNet.Core.Domain.Credentials;
using Revis.VClinicNet.UI.Internal.Mvc.Models;

namespace Revis.VClinicNet.UI.Internal.Mvc.Controllers
{
    public class WorkerUserController : Infrastructure.ControllerBase
    {
        private IWorkerUserService _workerUserService = null;

        public WorkerUserController(IWorkerUserService iwus) :
            base("WorkerUser")
        {
            _workerUserService = iwus;
        }

        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator)]
        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// Action to display worker user create form
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator)]
        public ActionResult Create()
        {
            return View(new WorkerUserCreateFormModel());
        }

        /// <summary>
        /// Create new worker user
        /// </summary>
        /// <param name="createDto">create worker user model</param>
        /// <returns></returns>
        [HttpPost]
        [HistoryBackLinked(Type = BackLinkType.ModifyForm)]
        [AuthorizeFor(Role = WorkerUserRole.Administrator)]
        public ActionResult Create(WorkerUserCreateDto createDto)
        {
            try {
                long id = _workerUserService.Create(createDto);
                return RedirectToAction("Detail", new { id = id });
            } catch (ValidationException ve) {
                ModelState.AddModelErrors(ve);
            } catch (ClinicException ce) {
                ModelState.AddErrorMessage(ce.Message);
            }
            return View(new WorkerUserCreateFormModel(createDto));
        }

        /// <summary>
        /// Action to display edit form 
        /// </summary>
        /// <param name="id">worker user id</param>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator)]
        public ActionResult Edit(long id)
        {
            WorkerUserEditDto user = _workerUserService.Find<WorkerUserEditDto>(id);
            if (user == null) {
                return ErrorView("Nie znaleziono pracownika", "Edit");
            }
            return View(user);
        }

        /// <summary>
        /// Edit worker user
        /// </summary>
        /// <param name="editDto">worker user edit model</param>
        /// <returns></returns>
        [HttpPost]
        [HistoryBackLinked(Type = BackLinkType.ModifyForm)]
        [AuthorizeFor(Role = WorkerUserRole.Administrator)]
        public ActionResult Edit(WorkerUserEditDto editDto)
        {
            try {
                _workerUserService.Edit(editDto);
                return RedirectToAction("Detail", new { id = editDto.Id });
            } catch (ValidationException ve) {
                ModelState.AddModelErrors(ve);
            } catch (ClinicException ce) {
                ModelState.AddErrorMessage(ce.Message);
            }
            return View(editDto);
        }

        /// <summary>
        /// Action to display change password form
        /// </summary>
        /// <param name="id">worker user id</param>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator)]
        public ActionResult Password(long id)
        {
            WorkerUserInfoDto user = _workerUserService.Find<WorkerUserInfoDto>(id);
            if (user == null) {
                return ErrorView("Nie znaleziono pracownika", "Password");
            }
            return View(new WorkerUserModifyPasswordDto() { Id = user.Id });
        }

        /// <summary>
        /// Change worker user password 
        /// </summary>
        /// <param name="passwordDto">change password model</param>
        /// <returns></returns>
        [HttpPost]
        [HistoryBackLinked(Type = BackLinkType.ModifyForm)]
        [AuthorizeFor(Role = WorkerUserRole.Administrator)]
        public ActionResult Password(WorkerUserModifyPasswordDto passwordDto)
        {
            try {
                _workerUserService.ChangePassword(passwordDto);
                return RedirectToAction("Detail", new { id = passwordDto.Id });
            } catch (ValidationException ve) {
                ModelState.AddModelErrors(ve);
            } catch (ClinicException ce) {
                ModelState.AddErrorMessage(ce.Message);
            }
            return View(passwordDto);
        }

        /// <summary>
        /// Action to display details of worker user
        /// </summary>
        /// <param name="id">worker user id</param>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Doctor | WorkerUserRole.Recepcionist)]
        public ActionResult Detail(long id)
        {
            WorkerUserDto user = _workerUserService.Find<WorkerUserDto>(id);
            if (user == null) {
                return ErrorView("Nie znaleziono pracownika", "Edit");
            }
            return View(user);
        }

        /// <summary>
        /// List of worker users in json format for search purposes
        /// </summary>
        /// <param name="field">field to search on</param>
        /// <param name="value">value of searched field</param>
        /// <param name="activity">is active worker user flag</param>
        /// <returns></returns>
        [HttpPost]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Doctor | WorkerUserRole.Recepcionist)]
        public ActionResult JsonWorkerInfos(string field, string value, bool activity)
        {
            IList<WorkerUserInfoDto> workerUsers = _workerUserService.FindBy(field, value, activity);
            workerUsers = workerUsers ?? new List<WorkerUserInfoDto>();
            return Json(workerUsers);
        }

        /// <summary>
        /// Display delete confirmation view
        /// </summary>
        /// <param name="id">worker user id</param>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator)]
        public ActionResult Delete(long id)
        {
            WorkerUserInfoDto user = _workerUserService.Find<WorkerUserInfoDto>(id);
            if (user == null) {
                return ErrorView("Nie znaleziono pracownika", "Edit");
            }
            return View(user);
        }

        /// <summary>
        /// Delete worker user (deactivate)
        /// </summary>
        /// <param name="id">worker user id</param>
        /// <returns></returns>
        [HttpPost]
        [HistoryBackLinked(Type = BackLinkType.ModifyForm)]
        [AuthorizeFor(Role = WorkerUserRole.Administrator)]
        public ActionResult DeleteWorkerUser(long id)
        {
            try {
                _workerUserService.Delete(id);
            } catch (ClinicException ce) {
                return View("Error", new HandleErrorInfo(ce, "WorkerUser", "DeleteWorkerUser"));
            }
            return Redirect(this.BackLinkUrl());
        }

    }
}
